﻿#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>



void logStrTemp(char *str);
//void logStr(char *str, FILE *outfile);
int initLog(const char *filenameprefix_, int isOpenTemp_ );
void addLineCount();
void addLineCountTemp();
void renamefiles();
void renamefilestemp();
void closefile();
void closefiletemp();
void openfile();
void openfiletemp();
void printTo(FILE *fileptr, const struct tm *local,const struct timeval *tv, const char *buf);
void getTime(struct tm *local, struct timeval *tv);
void printTo(FILE *fileptr, const struct tm *local,const struct timeval *tv, const char *buf);
void printDateToFile(FILE *outfile);
void getfilename(char *filename, const char *filepath);


#define     nullptr     (NULL)
int isOpenTemp = 0;

static int fileCountMax = 2;
static int lineCountMax = 10000;
static char filenameprefix[128] = "my";
static char foldername[128] = "mylog";

static int lineCountUse = 0;
static FILE *outfile = nullptr;
static char filename[256] = "test";
static FILE *outfiletemp = nullptr;
static int lineCountUseTemp = 0;

int isToFile = 0;



int initLog2(const char *filenameprefix_, const int lineCountMax_, const int fileCountMax_, int isOpenTemp_ )
{
    fileCountMax = fileCountMax_;
    lineCountMax = lineCountMax_;
    initLog(filenameprefix_, isOpenTemp_);
    return 0;
}

int initLog(const char *filenameprefix_, int isOpenTemp_ )
{
    isOpenTemp = isOpenTemp_;
    strncpy(filenameprefix, filenameprefix_, 128);

    renamefiles();  
    openfile();
    if (isOpenTemp_)
    {
        renamefilestemp();
        openfiletemp();
    }

    isToFile = 1;
    return 0;
}



void genAllBuf(char *allBuf, const char *file, int line, const char *fun, const char *fmt, va_list args)
{
    char        contentBuf[1024] = {0};
    char  fileBuf[256] = {0};
    char  filename[64] = {0};
    getfilename(filename, file);
    snprintf(fileBuf, 256, "%s(%d)::%s:", filename, line, fun);

    char  timeBuf[64] = {0};
    struct tm local;
    struct timeval tv;
    getTime(&local, &tv);
    snprintf(timeBuf,1024, "%02d:%02d:%02d.%06d:",
            local.tm_hour,local.tm_min, local.tm_sec, tv.tv_usec);


   // va_list        args;
   // va_start(args,fmt);
    vsnprintf(contentBuf,1024 , fmt,args);
 //   va_end(args);

 //   char        allBuf[2048] = {0};
    int timeLen = strlen(timeBuf);
    int fileLen = strlen(fileBuf);
    int contentLen = strlen(contentBuf);
    strncpy(allBuf, timeBuf, timeLen);
    strncpy(allBuf + timeLen, fileBuf, fileLen);
    strncpy(allBuf + timeLen + fileLen, contentBuf, contentLen);
}

void logInfoTemp1(const char *file, int line, const char *fun, const char *fmt, ...)
{
    if (!isOpenTemp)
    {
        return;
    }
    va_list        args;
    va_start(args,fmt);
    char        allBuf[2048] = {0};
    genAllBuf(allBuf, file, line, fun, fmt, args);
    va_end(args);

    logStrTemp(allBuf);
}

void logInfo1(const char *file, int line, const char *fun, const char *fmt, ...)
{
    va_list        args;
    va_start(args,fmt);
    char        allBuf[2048] = {0};
    genAllBuf(allBuf, file, line, fun, fmt, args);
    va_end(args);
    logStr(allBuf);
    if (isOpenTemp)
    {
        logStrTemp(allBuf);
    }

}

void logInfoP( const char *fmt, ...)
{
    char        buf[1024] = {0};
    va_list        args;
    va_start(args,fmt);
    vsnprintf(buf,1024 , fmt,args);
    va_end(args);

    logStr(buf);
}
void logBuf(char *data, int len,const  char *pre_str, int printlen)
{
    char tmpstr[32];
    char buf1[2048] = {0};
    int maxlen = sizeof(buf1) / sizeof(buf1[0]);
    int curlen;
    int tmplen;

    if (-1 == printlen)
    {
        printlen = len;
    }
    snprintf(buf1,2048, "[%s](%7d):", pre_str, len);
    int i = 0;

    curlen = strlen(buf1);
    if (printlen > len)
    {
        printlen = len;
    }
    for (i = 0; i < printlen; i++)
    {
        sprintf(tmpstr, "%02d ", data[i]);
        if (i % 5 == 0)
        {
           sprintf(tmpstr, "  %02x ", data[i] & 0xff);
        }
        else
        {
            sprintf(tmpstr, "%02x ", data[i] & 0xff);
         }
        tmplen = strlen(tmpstr);
        if (curlen + tmplen < maxlen)
        {
            strncpy(buf1 + curlen,tmpstr, tmplen);
            curlen += tmplen;
        }
    }


    fprintf(stderr, "%s\r\n", buf1);

    if (!isToFile)
    {
        return;
    }
    struct tm local;
    struct timeval tv;
    getTime(&local, &tv);
    printTo(outfile, &local, &tv, buf1);
    addLineCount();
}


void getTime(struct tm *local, struct timeval *tv)
{
    time_t curTime = time(NULL);
    struct tm * local1=localtime(&curTime);
    memcpy((char*)local, (char*)local1,sizeof(struct tm));
    gettimeofday(tv, NULL);
}

void printTo(FILE *fileptr, const struct tm *local,const struct timeval *tv, const char *buf)
{
    if (nullptr == fileptr)
    {
        return;
    }
    if (stderr == fileptr)
    {
        fprintf(stderr, "%02d:%02d:%02d.%06d:%s",
               local->tm_hour,local->tm_min, local->tm_sec,
                tv->tv_usec, buf);
        fprintf(fileptr, "%s\n",  buf);
         return;
    }
    fprintf(fileptr, "%02d:%02d:%02d.%06d:",
            local->tm_hour,local->tm_min, local->tm_sec,
             tv->tv_usec);
    fprintf(fileptr, "%s\n",  buf);
    fflush(fileptr);
}

void renamefiles()
{

    char oldFilename[256];
    char newFilename[256];
    for (int i = fileCountMax - 2; i >= 0; i--)
    {
        sprintf(oldFilename, "%s/%s_log.%d", foldername, filenameprefix, i);
        sprintf(newFilename, "%s/%s_log.%d", foldername, filenameprefix, i + 1);
        remove(newFilename);
        rename(oldFilename, newFilename);
        fprintf(stderr, "log::addLineCount: [%s]->[%s]\n", oldFilename, newFilename);
    }
}

void renamefilestemp()
{
    char oldFilename[256];
    char newFilename[256];

    for (int i = 0; i >= 0; i--)
    {
        sprintf(oldFilename, "%s/%s_temp_log.%d", foldername, filenameprefix, i);
        sprintf(newFilename, "%s/%s_temp_log.%d", foldername, filenameprefix, i + 1);
        remove(newFilename);
        rename(oldFilename, newFilename);
        fprintf(stderr, "log::addLineCount: [%s]->[%s]\n", oldFilename, newFilename);
    }
}

void openfile()
{
    snprintf(filename,256, "mylog/%s_log.%d.txt", filenameprefix, 0);
    //fprintf(stderr, "openfile:22222222222222222,%x\n", outfile);
    outfile = fopen(filename, "w");
   // fprintf(stderr, "openfile:3333333333333,%x\n", outfile);
    if (NULL == outfile)
    {
        fprintf(stderr, "addLineCount:open file fail\n");
        exit(1);
    }
    lineCountUse = 0;
    printDateToFile(outfile);

}

void closefile()
{

    //fprintf(stderr, "closefile:1111111111,outfile=%x\n", outfile);
    if (nullptr == outfile)
    {
        return;
    }
    //fprintf(stderr, "closefile:22222222222222222,%x\n", outfile);
    fclose(outfile);
    //fprintf(stderr, "closefile:3333333333333333\n");
    outfile = nullptr;
    //fprintf(stderr, "closefile:44444444444444444\n");
}

void openfiletemp()
{
    sprintf(filename, "mylog/%s_temp_log.%d.txt", filenameprefix, 0);
    outfiletemp = fopen(filename, "w");
    if (NULL == outfiletemp)
    {
        fprintf(stderr, "addLineCount:open file fail\n");
        exit(1);
    }
    lineCountUseTemp = 0;
    printDateToFile(outfiletemp);
}

void closefiletemp()
{
    fprintf(stderr, "closefiletemp:%x", outfiletemp);
    if (nullptr == outfiletemp)
    {
        return;
    }
    fclose(outfiletemp);
    outfiletemp = nullptr;
}

void addLineCount()
{

    lineCountUse++;
    if (lineCountUse < lineCountMax)
    {
        return;
    }
    lineCountUse = 0;    
    closefile();
    renamefiles();
    openfile();
}

void addLineCountTemp()
{
    lineCountUseTemp++;
    if (lineCountUseTemp < lineCountMax)
    {
        return;
    }
    lineCountUseTemp = 0;
    closefiletemp();
    renamefilestemp();
    openfiletemp();
}

void printDateToFile(FILE *outfile)
{
    time_t t;
    struct tm * lt;
    time (&t);//获取Unix时间戳。
    lt = localtime (&t);//转为时间结构。
    fprintf(outfile, "==========%04d-%02d-%02d===%02d:%02d:%02d===============\n\r\n",
            lt->tm_year+1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);

}

void assertfun1(const char *file, int line,const char *fun, int condition, const char *errStr)
{
    if (condition)
    {
        logInfo1(file, line, fun, "%s.***********ERROR***********", errStr);
        exit(1);
    }
}



void getfilename(char *filename, const char *filepath)
{
    int len = strlen(filepath);
    int i;
    int index2;
    int index1;
    for (i = len - 1; i >= 0; i--)
    {
        if(filepath[i] == '.')
        {
            index2 = i;
            break;
        }
    }
    if (i < 0)
    {
        return;
    }
    for (; i >= 0; i--)
    {
        if(filepath[i] == '/' || filepath[i] == '\\')
        {
            index1 = i;
            break;
        }
    }
    if (i < 0)
    {
        return;
    }

    strncpy(filename, filepath + index1 + 1, index2 - index1 - 1);

}

void logStrTemp(char *str)
{
    if (nullptr == outfiletemp)
    {
        return;
    }
    fputs(str, outfiletemp);
    fputs("\n", outfiletemp);
    fflush(outfiletemp);
    addLineCountTemp();
}

void logStr(char *str)
{
    fputs(str, stderr);
    fputs("\n", stderr);

    if (nullptr == outfile)
    {
        return;
    }
    fputs(str, outfile);
    fputs("\n", outfile);
    fflush(outfile);
    addLineCount();
}
